package com.ly.heart.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.PageParam;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.core.domain.entity.SysUser;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.ReturnPage;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.common.utils.spring.SpringUtils;
import com.ly.heart.domain.*;
import com.ly.heart.domain.dto.KingReceiveNoticeMaterialQueryDto;
import com.ly.heart.domain.dto.KingReceiveNoticeQueryDto;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.common.core.domain.ActCurrentTaskVo;
import com.ly.heart.domain.vo.KingReceiveNoticeVo;
import com.ly.heart.domain.vo.OrderSumResult;
import com.ly.heart.domain.vo.select.KingReceiveNoticeSelectVo;
import com.ly.heart.domain.vo.select.query.KingReceiveNoticeSelectQueryDto;
import com.ly.heart.mapper.KingReceiveNoticeMapper;
import com.ly.heart.service.*;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import com.ly.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 金蝶-收料通知单Service业务层处理
 *
 * @author cxl
 * @date 2024-08-09
 */
@Service
public class KingReceiveNoticeServiceImpl extends ServiceImpl<KingReceiveNoticeMapper,KingReceiveNoticeEntity> implements IKingReceiveNoticeService {

    @Resource
    private KingReceiveNoticeMapper kingReceiveNoticeMapper;
    @Resource
    private ISysDeptService sysDeptService;
    @Resource
    private IKingReceiveNoticeMaterialService receiveNoticeMaterialService;
    @Resource
    private IKingReceiveNoticeMaterialDetailService receiveNoticeMaterialDetailService;
    @Resource
    private IKingReceiveNoticeMaterialDetailSerialService receiveNoticeMaterialDetailSerialService;
    @Resource
    private IKingReceiveNoticeLogisticsService receiveNoticeLogisticsService;
    @Resource
    private IOrderService orderService;
    @Resource
    private IMaterialDetailService materialDetailService;
    @Resource
    private IActModelService actModelService;
    @Resource
    private IActTaskCommentService actTaskCommentService;
    @Resource
    private IKingInventoryMaterialService inventoryMaterialService;
    @Resource
    private IKingCheckMaterialService checkMaterialService;
    @Resource
    private IKingCheckMaterialUseDecisionService checkMaterialUseDecisionService;
    @Resource
    private IKingBadHandleMaterialService badHandleMaterialService;
    @Resource
    private ISupplierService supplierService;
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private IKingBaseBusinessGroupDetailService kingBaseBusinessGroupDetailService;
    @Resource
    private ISupplierContactsService supplierContactsService;
    @Resource
    private IKingBaseSettlementTypeService kingBaseSettlementTypeService;
    @Resource
    private IKingBaseCurrencyService kingBaseCurrencyService;
    @Resource
    private IKingBaseReceiptPayConditionService kingBaseReceiptPayConditionService;
    @Resource
    private IKingBaseMeteringUnitService meteringUnitService;
    @Resource
    private IKingBaseInventoryStatusService inventoryStatusService;
    @Resource
    private IWarehouseService warehouseService;
    @Resource
    private IKingBaseContactsService baseContactsService;


    @Override
    public AjaxResult getKingReceiveNoticePageList(KingReceiveNoticeQueryDto queryDto){
        List<KingReceiveNoticeVo> list = receiveNoticeMaterialService.getReceiveNoticePageList(queryDto);
        list.forEach(receiveNoticeVo -> {
            ActTaskCommentEntity actTaskCommentEntity = actTaskCommentService.queryLastComment(receiveNoticeVo.getInstanceId());
            if ( actTaskCommentEntity != null ) {
                receiveNoticeVo.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                receiveNoticeVo.setRemark ( actTaskCommentEntity.getRemark () );
            }
            //任务信息
            ActCurrentTaskVo currentTaskVo = actModelService.getCurrentTaskByInstanceId(receiveNoticeVo.getInstanceId());
            Optional.ofNullable(currentTaskVo).ifPresent(receiveNoticeVo::setCurrentTask);

            KingReceiveNoticeMaterialQueryDto materialQueryDto = new KingReceiveNoticeMaterialQueryDto();
            materialQueryDto.setReceiveNoticeId(receiveNoticeVo.getId());
            materialQueryDto.setMaterialDetailId(receiveNoticeVo.getMaterialDetailId());
            //累计入库数量(入库单源单为收料通知单1及行号，物料入库数量求和)
            OrderSumResult inventorySumResult = inventoryMaterialService.selectSumReceiptsNumByReceiveNotice(materialQueryDto);
            receiveNoticeVo.setTotalInventoryNum(inventorySumResult.getTotalNum());
            //检验数量
            String checkNum = checkMaterialService.getTotalCheckNumByReceiveNotice(materialQueryDto);
            receiveNoticeVo.setCheckNum(checkNum);
            //合格数量
            String qualifiedNum = checkMaterialService.getTotalQualifiedNumByReceiveNotice(materialQueryDto);
            receiveNoticeVo.setQualifiedNum(qualifiedNum);
            //判退数量
            KingReceiveNoticeMaterialQueryDto rejectQueryDto = new KingReceiveNoticeMaterialQueryDto();
            rejectQueryDto.setReceiveNoticeId(receiveNoticeVo.getId());
            rejectQueryDto.setMaterialDetailId(receiveNoticeVo.getMaterialDetailId());
            rejectQueryDto.setUseDecision(ConstUtil.CHECK_DECISION_REJECT);
            String rejectNum = checkMaterialUseDecisionService.getTotalDecisionNumByByReceiveNotice(rejectQueryDto);
            receiveNoticeVo.setRejectNum(rejectNum);
            //让步接收数量
            KingReceiveNoticeMaterialQueryDto concessionAcceptanceQueryDto = new KingReceiveNoticeMaterialQueryDto();
            concessionAcceptanceQueryDto.setReceiveNoticeId(receiveNoticeVo.getId());
            concessionAcceptanceQueryDto.setMaterialDetailId(receiveNoticeVo.getMaterialDetailId());
            concessionAcceptanceQueryDto.setUseDecision(ConstUtil.CHECK_DECISION_CONCESSION_ACCEPT);
            String concessionAcceptanceNum = checkMaterialUseDecisionService.getTotalDecisionNumByByReceiveNotice(concessionAcceptanceQueryDto);
            receiveNoticeVo.setConcessionAcceptanceNum(concessionAcceptanceNum);
            //不良品折让金额(收料通知单下推检验单，检验不良下推不良品，求不良品的折让金额)
            List<KingCheckMaterialEntity> checkMaterialList = checkMaterialService.getKingCheckMaterialListByReceiveNotice(materialQueryDto);
            Map<String, String> idDetailMap = checkMaterialList.stream().collect(Collectors.toMap(KingCheckMaterialEntity::getCheckId, KingCheckMaterialEntity::getId));
            LambdaQueryWrapper<KingBadHandleMaterialEntity> badHandleQuery = new LambdaQueryWrapper<>();
            idDetailMap.forEach((id, detailId) -> {
                badHandleQuery.or(wrapper -> wrapper.eq(KingBadHandleMaterialEntity::getRelationId, id).eq(KingBadHandleMaterialEntity::getSourceMaterialDetailId, detailId));
            });
            List<KingBadHandleMaterialEntity> badHandleMaterialList = badHandleMaterialService.list(badHandleQuery);
            double badDiscountAmount = badHandleMaterialList.stream().map(badHandleMaterial -> {
                return Optional.ofNullable(badHandleMaterial.getDiscountAmount()).map(amount -> {
                    try {
                        return Double.parseDouble(amount);
                    } catch (NumberFormatException e) {
                        return 0.0;
                    }
                }).orElse(0.0);
            }).mapToDouble(Double::doubleValue).sum();
            receiveNoticeVo.setBadDiscountAmount(String.valueOf(badDiscountAmount));
        });
        Page<KingReceiveNoticeVo> page = new Page<>(queryDto.getPage(),queryDto.getLimit());
        return AjaxResult.success(ReturnPage.getReturnPage(page,list));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult draft(KingReceiveNoticeEntity kingReceiveNotice){
        if(StringUtils.isEmpty(kingReceiveNotice.getId())){
            //设置收料通知单基础信息
            String receiveNoticeId = SnowflakeIdWorker.getInstance().nextStringId();
            Date nowDate = DateUtils.getNowDate();
            String userId = SecurityUtils.getLoginUser().getUser().getUserId();
            //设置收料单基本信息
            kingReceiveNotice.setId(receiveNoticeId).setUserId(userId).setCreateTime(nowDate).setCreateName(SecurityUtils.getUsername());
            //收料单号生成
            if(StringUtils.isEmpty(kingReceiveNotice.getDocCode())){
                String companyId = CurrentUserUtil.getCompanyId();
                SysDept sysDept = sysDeptService.getById(companyId);
                int count = kingReceiveNoticeMapper.queryCount();
                String countStr = String.format("%06d", count);
                String firstLetter = ChineseToPinyin.getFirstLetter(sysDept.getDeptName());
                String docCode = firstLetter.concat("_SLTD_").concat(countStr);
                kingReceiveNotice.setDocCode(docCode);
            }
            //流程状态：暂存
            kingReceiveNotice.setState(ConstUtil.STATE_IN_DRAFT);
            //保存物料以及其他数据
            if(!CollectionUtils.isEmpty(kingReceiveNotice.getMaterialLists())){
                saveMaterialAndDetail(kingReceiveNotice.getMaterialLists(),kingReceiveNotice);
            }
            //保存物流跟踪信息
            if(!CollectionUtils.isEmpty(kingReceiveNotice.getLogisticsList())){
                saveLogistics(kingReceiveNotice.getLogisticsList(),kingReceiveNotice);
            }
            //设置货主类型以及货主
            kingReceiveNotice.setCargoOwnerType("BD_Supplier");
            kingReceiveNotice.setCargoOwner(kingReceiveNotice.getSupplierCode());

            boolean saveFlag = this.save(kingReceiveNotice);
            if (saveFlag) {
                return AjaxResult.success("暂存收料通知单成功！",kingReceiveNotice.getId());
            }
            return AjaxResult.error("暂存收料通知单失败！");
        }else{
            return update(kingReceiveNotice);
        }
    }

    /**
     * 提交收料通知单(采购订单下推收料通知单)
     * @param kingReceiveNotice
     * @return
     *  1.数量验收：交货数量字段可修改，但不能超过采购订单数量；当收料单审核完毕后将交货数量反写到采购订单
     *  2.金额验收：行价税合计字段可以修改，税价合计/含税单价 反算出交货数量 ，反写到采购订单
     *  3.比例验收：锁定交货数量，税价合计字段，根据交货比例（金蝶叫验收比例）根据比例计算交货数量，反写采购订单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submit(KingReceiveNoticeEntity kingReceiveNotice){
        if(Objects.isNull(kingReceiveNotice.getId())){
            return AjaxResult.error("收料通知单id不能为空！");
        }
        if(CollectionUtils.isEmpty(kingReceiveNotice.getMaterialLists())){
            return AjaxResult.error("物料信息不能为空！");
        }
        //校验物料信息
        List<KingReceiveNoticeMaterialEntity> materialLists = kingReceiveNotice.getMaterialLists();
        List<String> orderIdList = materialLists.stream().filter(Objects::nonNull).distinct().map(KingReceiveNoticeMaterialEntity::getRelationId).collect(Collectors.toList());
        List<OrderEntity> orderList = orderService.list(new QueryWrapper<OrderEntity>().in("id", orderIdList));
        //判断供应商是否不同
        List<String> supplierIdList = orderList.stream().filter(Objects::nonNull).distinct().map(OrderEntity::getSupplierId).collect(Collectors.toList());
        if (!supplierIdList.isEmpty() && supplierIdList.size() >= 2) {
            return AjaxResult.error("所选单据供应商不一致，无法操作！");
        }
        //判断采购组织是否不同
        List<String> purchaseOrgList = orderList.stream().filter(Objects::nonNull).distinct().map(OrderEntity::getPurchaseOrg).collect(Collectors.toList());
        if (!purchaseOrgList.isEmpty() && purchaseOrgList.size() >= 2) {
            return AjaxResult.error("所选单据采购组织不一致，无法操作！");
        }
        //判断币别是否不同
        List<String> settlementCurrencyList = orderList.stream().filter(Objects::nonNull).distinct().map(OrderEntity::getSettlementCurrency).collect(Collectors.toList());
        if (!settlementCurrencyList.isEmpty() && settlementCurrencyList.size() >= 2) {
            return AjaxResult.error("所选单据结算币别不一致，无法操作！");
        }
        //检查物料明细数量
        checkMaterialNum(materialLists);
        //数量检查完后先删除暂存时保存的其他信息
        removeKingReceiveNotice(kingReceiveNotice.getId());
        //保存物料以及其他数据
        if(!CollectionUtils.isEmpty(kingReceiveNotice.getMaterialLists())){
            saveMaterialAndDetail(kingReceiveNotice.getMaterialLists(),kingReceiveNotice);
        }
        //保存物流跟踪信息
        if(!CollectionUtils.isEmpty(kingReceiveNotice.getLogisticsList())){
            saveLogistics(kingReceiveNotice.getLogisticsList(),kingReceiveNotice);
        }
        //启动审批流程
        StartProcessDto startDto = new StartProcessDto().setBusinessId(kingReceiveNotice.getId()).setBusinessType(kingReceiveNotice.getBusinessType()).setModelId(kingReceiveNotice.getModelId());
        startDto.setBusinessName("收料通知单_".concat(kingReceiveNotice.getDocCode()));
        String instanceId = actModelService.startProcess(startDto);
        kingReceiveNotice.setState(ConstUtil.STATE_IN_PROCESS).setInstanceId(instanceId);
        boolean updated = this.updateById(kingReceiveNotice);
        if(!updated){
            return AjaxResult.error("提交收料通知单失败！");
        }
        return AjaxResult.success("提交收料通知单成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(KingReceiveNoticeEntity kingReceiveNotice){
        if(StringUtils.isEmpty(kingReceiveNotice.getId())){
            return AjaxResult.error("收料通知单id不能为空！");
        }
        //数量检查完后先删除暂存时保存的其他信息
        removeKingReceiveNotice(kingReceiveNotice.getId());
        //保存物料以及其他数据
        if(!CollectionUtils.isEmpty(kingReceiveNotice.getMaterialLists())){
            saveMaterialAndDetail(kingReceiveNotice.getMaterialLists(),kingReceiveNotice);
        }
        //保存物流跟踪信息
        if(!CollectionUtils.isEmpty(kingReceiveNotice.getLogisticsList())){
            saveLogistics(kingReceiveNotice.getLogisticsList(),kingReceiveNotice);
        }
        boolean updated = this.updateById(kingReceiveNotice);
        if(!updated){
            return AjaxResult.error("修改失败！");
        }
        return AjaxResult.success("修改成功！",kingReceiveNotice.getId());
    }

    /**
     * 检查物料数量和金额是否超源单
     * @param materialLists
     */
    private void checkMaterialNum(List<KingReceiveNoticeMaterialEntity> materialLists){
        materialLists.forEach(receiveNoticeMaterial -> {
            //1.判断源单id
            if(Objects.nonNull(receiveNoticeMaterial.getSourceMaterialDetailId())){
                //2.采购订单原数量
                MaterialDetailEntity orderDetail = materialDetailService.getById(receiveNoticeMaterial.getSourceMaterialDetailId());
                double orderNumber = Double.parseDouble(orderDetail.getNumber());
                //3.查询源单采购订单该物料已经下推收料通知单的数量
                List<KingReceiveNoticeMaterialEntity> receiveNoticeMaterials = receiveNoticeMaterialService.list(new LambdaUpdateWrapper<KingReceiveNoticeMaterialEntity>().ne(KingReceiveNoticeMaterialEntity::getReceiveNoticeId,receiveNoticeMaterial.getReceiveNoticeId()).eq(KingReceiveNoticeMaterialEntity::getRelationId, receiveNoticeMaterial.getRelationId()).eq(KingReceiveNoticeMaterialEntity::getSourceMaterialDetailId, receiveNoticeMaterial.getSourceMaterialDetailId()));
                //4.查询源单采购订单该物料已经有下推入库单的数量
                IKingInventoryMaterialService inventoryMaterialService = SpringUtils.getBean(IKingInventoryMaterialService.class);
                List<KingInventoryMaterialEntity> inventoryMaterials = inventoryMaterialService.list(new LambdaQueryWrapper<KingInventoryMaterialEntity>().eq(KingInventoryMaterialEntity::getRelationId, receiveNoticeMaterial.getRelationId()).eq(KingInventoryMaterialEntity::getSourceMaterialDetailId, receiveNoticeMaterial.getSourceMaterialDetailId()));
                //5.获取已下推总数量
                double sumReceiveNum = 0;
                double sumInventoryNum = 0;
                if(!CollectionUtils.isEmpty(receiveNoticeMaterials)){
                    sumReceiveNum = receiveNoticeMaterials.stream().mapToDouble(material -> Double.parseDouble(material.getDeliveryNum())).sum();
                }
                if(!CollectionUtils.isEmpty(inventoryMaterials)){
                    sumInventoryNum = inventoryMaterials.stream().mapToDouble(material -> Double.parseDouble(material.getReceiptsNum())).sum();
                }
                //6.判断剩余可引用数量
                double surplusNum = orderNumber - sumReceiveNum - sumInventoryNum;
                if (Double.parseDouble(receiveNoticeMaterial.getDeliveryNum()) > surplusNum) {
                    throw new RuntimeException("引用数量不能超过采购订单数量！");
                }
            }
        });
    }

    /**
     * 保存物料信息和其他信息
     * @param materialLists
     * @param kingReceiveNotice
     */
    private void saveMaterialAndDetail(List<KingReceiveNoticeMaterialEntity> materialLists,KingReceiveNoticeEntity kingReceiveNotice){
        materialLists.forEach(receiveNoticeMaterial -> {
            String receiveNoticeMaterialId = SnowflakeIdWorker.getInstance().nextStringId();
            receiveNoticeMaterial.setId(receiveNoticeMaterialId);
            receiveNoticeMaterial.setReceiveNoticeId(kingReceiveNotice.getId());
            receiveNoticeMaterial.setUserId(kingReceiveNotice.getUserId());
            receiveNoticeMaterial.setCreateTime(kingReceiveNotice.getCreateTime());
            //计算应交数量
            if(StringUtils.isNotEmpty(receiveNoticeMaterial.getSourceType())){
                MaterialDetailEntity orderDetail = materialDetailService.getById(receiveNoticeMaterial.getSourceMaterialDetailId());
                double orderNumber = Double.parseDouble(orderDetail.getNumber());
                double sumReceiveNum = 0;
                double sumInventoryNum = 0;
                List<KingReceiveNoticeMaterialEntity> receiveNoticeMaterials = receiveNoticeMaterialService.list(new LambdaUpdateWrapper<KingReceiveNoticeMaterialEntity>().ne(KingReceiveNoticeMaterialEntity::getReceiveNoticeId,receiveNoticeMaterial.getReceiveNoticeId()).eq(KingReceiveNoticeMaterialEntity::getRelationId, receiveNoticeMaterial.getRelationId()).eq(KingReceiveNoticeMaterialEntity::getSourceMaterialDetailId, receiveNoticeMaterial.getSourceMaterialDetailId()));
                IKingInventoryMaterialService inventoryMaterialService = SpringUtils.getBean(IKingInventoryMaterialService.class);
                List<KingInventoryMaterialEntity> inventoryMaterials = inventoryMaterialService.list(new LambdaQueryWrapper<KingInventoryMaterialEntity>().eq(KingInventoryMaterialEntity::getRelationId, receiveNoticeMaterial.getRelationId()).eq(KingInventoryMaterialEntity::getSourceMaterialDetailId, receiveNoticeMaterial.getSourceMaterialDetailId()));
                if(!CollectionUtils.isEmpty(receiveNoticeMaterials)){
                    sumReceiveNum = receiveNoticeMaterials.stream().mapToDouble(material -> Double.parseDouble(material.getDeliveryNum())).sum();
                }
                if(!CollectionUtils.isEmpty(inventoryMaterials)){
                    sumInventoryNum = inventoryMaterials.stream().mapToDouble(material -> Double.parseDouble(material.getReceiptsNum())).sum();
                }
                double surplusNum = orderNumber - sumReceiveNum - sumInventoryNum;
                receiveNoticeMaterial.setShouldSubmitNum(String.valueOf(surplusNum));
            }
            boolean receiveNoticeMaterialFlag = receiveNoticeMaterialService.save(receiveNoticeMaterial);
            if(!receiveNoticeMaterialFlag){
                throw new RuntimeException("新增收料通知单物料失败！");
            }
            Optional.ofNullable(receiveNoticeMaterial.getMaterialDetail()).ifPresent(materialDetail -> {
                String materialDetailId = SnowflakeIdWorker.getInstance().nextStringId();
                materialDetail.setId(materialDetailId);
                materialDetail.setReceiveNoticeId(kingReceiveNotice.getId());
                materialDetail.setReceiveNoticeMaterialId(receiveNoticeMaterialId);
                materialDetail.setUserId(receiveNoticeMaterial.getUserId());
                materialDetail.setCreateTime(receiveNoticeMaterial.getCreateTime());
                boolean materialDetailFlag = receiveNoticeMaterialDetailService.save(materialDetail);
                if(!materialDetailFlag){
                    throw new RuntimeException("新增收料通知单物料明细失败！");
                }
                if (!CollectionUtils.isEmpty(materialDetail.getMaterialDetailSerials())) {
                    List<KingReceiveNoticeMaterialDetailSerialEntity> materialDetailSerials = materialDetail.getMaterialDetailSerials();
                    for(KingReceiveNoticeMaterialDetailSerialEntity materialDetailSerial : materialDetailSerials){
                        materialDetailSerial.setId(SnowflakeIdWorker.getInstance().nextStringId());
                        materialDetailSerial.setReceiveNoticeId(kingReceiveNotice.getId());
                        materialDetailSerial.setReceiveNoticeMaterialId(receiveNoticeMaterial.getId());
                        materialDetailSerial.setMaterialDetailId(materialDetail.getId());
                        receiveNoticeMaterialDetailSerialService.save(materialDetailSerial);
                    }
                }
            });
        });
    }

    /**
     * 保存物流跟踪信息
     * @param logisticsList
     */
    private void saveLogistics(List<KingReceiveNoticeLogisticsEntity> logisticsList,KingReceiveNoticeEntity kingReceiveNotice){
        for(KingReceiveNoticeLogisticsEntity receiveNoticeLogistics : logisticsList){
            receiveNoticeLogistics.setId(SnowflakeIdWorker.getInstance().nextStringId());
            receiveNoticeLogistics.setReceiveNoticeId(kingReceiveNotice.getId());
            receiveNoticeLogistics.setUserId(kingReceiveNotice.getUserId());
            receiveNoticeLogistics.setCreateTime(kingReceiveNotice.getCreateTime());
            boolean save = receiveNoticeLogisticsService.save(receiveNoticeLogistics);
            if(!save){
               throw new RuntimeException("新增收料通知单物流跟踪信息失败！");
            }
        }
    }

    /**
     * 查询金蝶-收料通知单
     *
     * @param id 金蝶-收料通知单ID
     * @return 金蝶-收料通知单
     */
    @Override
    public KingReceiveNoticeEntity selectKingReceiveNoticeEntityById(String id)
    {
        KingReceiveNoticeEntity kingReceiveNoticeEntity = kingReceiveNoticeMapper.selectKingReceiveNoticeEntityById(id);
        Optional.ofNullable(kingReceiveNoticeEntity).ifPresent(kingReceiveNotice -> {
            //收料组织
            SysDept receiveOrg = sysDeptService.getOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptCode,kingReceiveNotice.getReceiveOrgCode()));
            Optional.ofNullable(receiveOrg).ifPresent(r -> {
                kingReceiveNotice.setReceiveOrgName(r.getDeptName());
            });
            //采购组织
            SysDept purchaseOrg = sysDeptService.getOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptCode,kingReceiveNotice.getPurchaseOrgCode()));
            Optional.ofNullable(purchaseOrg).ifPresent(r -> {
                kingReceiveNotice.setPurchaseOrgName(r.getDeptName());
            });
            //收料部门
            SysDept receiveDept = sysDeptService.getOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptCode,kingReceiveNotice.getReceiveDeptCode()));
            Optional.ofNullable(receiveDept).ifPresent(r -> {
                kingReceiveNotice.setReceiveDeptName(r.getDeptName());
            });
            //采购部门
            SysDept purchaseDept = sysDeptService.getOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptCode,kingReceiveNotice.getPurchaseDeptCode()));
            Optional.ofNullable(purchaseDept).ifPresent(r -> {
                kingReceiveNotice.setPurchaseDeptName(r.getDeptName());
            });
            //库存组
            KingBaseBusinessGroupDetailEntity inventoryGroupDetail = kingBaseBusinessGroupDetailService.getOne(new LambdaQueryWrapper<KingBaseBusinessGroupDetailEntity>().eq(KingBaseBusinessGroupDetailEntity::getBusinessCode, kingReceiveNotice.getInventoryGroup()));
            Optional.ofNullable(inventoryGroupDetail).ifPresent(b -> {
                kingReceiveNotice.setInventoryGroupName(b.getBusinessName());
            });
            //采购组
            KingBaseBusinessGroupDetailEntity purchaseGroupDetail = kingBaseBusinessGroupDetailService.getOne(new LambdaQueryWrapper<KingBaseBusinessGroupDetailEntity>().eq(KingBaseBusinessGroupDetailEntity::getBusinessCode, kingReceiveNotice.getPurchaseGroup()));
            Optional.ofNullable(purchaseGroupDetail).ifPresent(b -> {
                kingReceiveNotice.setPurchaseGroupName(b.getBusinessName());
            });
            //收料员
            SysUser receiveBy = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserCode,kingReceiveNotice.getReceiveBy()));
            Optional.ofNullable(receiveBy).ifPresent(r -> {
                kingReceiveNotice.setReceiveByName(r.getUserName());
            });
            //采购员
            SysUser purchaseBy = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserCode, kingReceiveNotice.getPurchaseBy()));
            Optional.ofNullable(purchaseBy).ifPresent(r -> {
                kingReceiveNotice.setPurchaseByName(r.getUserName());
            });
            //供应商名称
            SupplierEntity supplierEntity = supplierService.getById(kingReceiveNotice.getSupplierId());
            Optional.ofNullable(supplierEntity).ifPresent(s -> {
                kingReceiveNotice.setSupplierName(s.getSupplierName());
            });
            //供货方名称
            SupplierEntity providerName = supplierService.getById(kingReceiveNotice.getProviderId());
            Optional.ofNullable(providerName).ifPresent(p -> {
                kingReceiveNotice.setProviderName(p.getSupplierName());
            });
            //供货方联系人名称
            KingBaseContactsEntity baseContactsEntity = baseContactsService.getOne(new LambdaQueryWrapper<KingBaseContactsEntity>().eq(KingBaseContactsEntity::getContactsCode, kingReceiveNotice.getProviderContacts()));
            Optional.ofNullable(baseContactsEntity).ifPresent(b -> {
                kingReceiveNotice.setProviderContactsName(b.getName());
            });
            //结算方名称
            SupplierEntity balanceName = supplierService.getById(kingReceiveNotice.getBalanceId());
            Optional.ofNullable(balanceName).ifPresent(b -> {
                kingReceiveNotice.setBalanceName(b.getSupplierName());
            });
            //收款方名称
            SupplierEntity receiveName = supplierService.getById(kingReceiveNotice.getReceiveId());
            Optional.ofNullable(receiveName).ifPresent(r -> {
                kingReceiveNotice.setReceiveName(r.getSupplierName());
            });
            //结算组织名称
            SysDept balanceOrgName = sysDeptService.getById(kingReceiveNotice.getBalanceOrg());
            Optional.ofNullable(balanceOrgName).ifPresent(b -> {
                kingReceiveNotice.setBalanceOrgName(b.getDeptName());
            });
            //结算方式名称
            KingBaseSettlementTypeEntity kingBaseSettlementType = kingBaseSettlementTypeService.getOne(new LambdaQueryWrapper<KingBaseSettlementTypeEntity>().eq(KingBaseSettlementTypeEntity::getBizCode, kingReceiveNotice.getSettlementMethod()));
            Optional.ofNullable(kingBaseSettlementType).ifPresent(k -> {
                kingReceiveNotice.setSettlementMethodName(k.getTitle());
            });
            //结算币别名称
            KingBaseCurrencyEntity KingBaseCurrency = kingBaseCurrencyService.getOne(new LambdaQueryWrapper<KingBaseCurrencyEntity>().eq(KingBaseCurrencyEntity::getCode, kingReceiveNotice.getSettlementCurrency()));
            Optional.ofNullable(KingBaseCurrency).ifPresent(k -> {
                kingReceiveNotice.setSettlementCurrencyName(k.getCurrencyName());
            });
            //付款条件名称
            KingBaseReceiptPayConditionEntity receiptPayCondition = kingBaseReceiptPayConditionService.getOne(new LambdaQueryWrapper<KingBaseReceiptPayConditionEntity>().eq(KingBaseReceiptPayConditionEntity::getConditionCode, kingReceiveNotice.getTermOfPayment()));
            Optional.ofNullable(receiptPayCondition).ifPresent(r -> {
                kingReceiveNotice.setTermOfPaymentName(r.getTitle());
            });
            //物料信息
            List<KingReceiveNoticeMaterialEntity> materialLists = receiveNoticeMaterialService.list(new LambdaUpdateWrapper<KingReceiveNoticeMaterialEntity>().eq(KingReceiveNoticeMaterialEntity::getReceiveNoticeId, kingReceiveNotice.getId()));
            if(!CollectionUtils.isEmpty(materialLists)){
                for(KingReceiveNoticeMaterialEntity receiveNoticeMaterial : materialLists){
                    //仓库名称
                    if(!StringUtils.isEmpty(receiveNoticeMaterial.getWarehouseCode())){
                        WarehouseEntity warehouseEntity = warehouseService.getOne(new LambdaQueryWrapper<WarehouseEntity>().eq(WarehouseEntity::getWareCode, receiveNoticeMaterial.getWarehouseCode()));
                        Optional.ofNullable(warehouseEntity).ifPresent(warehouse -> {
                            receiveNoticeMaterial.setWarehouseName(warehouse.getWareName());
                        });
                    }
                    //收料单位名称
                    KingBaseMeteringUnitEntity receiveUnit = meteringUnitService.getOne(new LambdaQueryWrapper<KingBaseMeteringUnitEntity>().eq(KingBaseMeteringUnitEntity::getMeteringUnitCode, receiveNoticeMaterial.getReceiveUnit()));
                    Optional.ofNullable(receiveUnit).ifPresent(r -> {
                        receiveNoticeMaterial.setReceiveUnitName(r.getMeteringUnitName());
                    });
                    //计价单位名称
                    KingBaseMeteringUnitEntity pricingUnitName = meteringUnitService.getOne(new LambdaQueryWrapper<KingBaseMeteringUnitEntity>().eq(KingBaseMeteringUnitEntity::getMeteringUnitCode, receiveNoticeMaterial.getPricingUnit()));
                    Optional.ofNullable(pricingUnitName).ifPresent(p -> {
                        receiveNoticeMaterial.setPricingUnitName(p.getMeteringUnitName());
                    });
                    //库存单位名称
                    if(StringUtils.isNotEmpty(receiveNoticeMaterial.getInventoryUnit())){
                        KingBaseMeteringUnitEntity inventoryUnit = meteringUnitService.getOne(new LambdaQueryWrapper<KingBaseMeteringUnitEntity>().eq(KingBaseMeteringUnitEntity::getMeteringUnitCode, receiveNoticeMaterial.getInventoryUnit()));
                        Optional.ofNullable(inventoryUnit).ifPresent(i -> {
                            receiveNoticeMaterial.setInventoryUnitName(i.getMeteringUnitName());
                        });
                    }
                    //库存状态名称
                    if(StringUtils.isNotEmpty(receiveNoticeMaterial.getInventoryStatus())){
                        KingBaseInventoryStatusEntity baseInventoryStatusEntity = inventoryStatusService.getOne(new LambdaQueryWrapper<KingBaseInventoryStatusEntity>().eq(KingBaseInventoryStatusEntity::getInventoryStatusCode, receiveNoticeMaterial.getInventoryStatus()));
                        Optional.ofNullable(baseInventoryStatusEntity).ifPresent(i -> {
                            receiveNoticeMaterial.setInventoryStatusName(i.getInventoryStatusName());
                        });
                    }
                    KingReceiveNoticeMaterialDetailEntity receiveNoticeMaterialDetail = receiveNoticeMaterialDetailService.getOne(new LambdaUpdateWrapper<KingReceiveNoticeMaterialDetailEntity>().eq(KingReceiveNoticeMaterialDetailEntity::getReceiveNoticeId, kingReceiveNotice.getId()).eq(KingReceiveNoticeMaterialDetailEntity::getReceiveNoticeMaterialId, receiveNoticeMaterial.getId()));
                    if(Objects.nonNull(receiveNoticeMaterialDetail)){
                        List<KingReceiveNoticeMaterialDetailSerialEntity> serialLists = receiveNoticeMaterialDetailSerialService.list(new LambdaUpdateWrapper<KingReceiveNoticeMaterialDetailSerialEntity>()
                        .eq(KingReceiveNoticeMaterialDetailSerialEntity::getReceiveNoticeId, kingReceiveNotice.getId()).eq(KingReceiveNoticeMaterialDetailSerialEntity::getReceiveNoticeMaterialId, receiveNoticeMaterial.getId())
                        .eq(KingReceiveNoticeMaterialDetailSerialEntity::getMaterialDetailId, receiveNoticeMaterialDetail.getId()));
                        receiveNoticeMaterialDetail.setMaterialDetailSerials(serialLists);
                    }
                    receiveNoticeMaterial.setMaterialDetail(receiveNoticeMaterialDetail);
                }
                kingReceiveNotice.setMaterialLists(materialLists);
            }
            //物流跟踪信息
            List<KingReceiveNoticeLogisticsEntity> logisticsList = receiveNoticeLogisticsService.list(new QueryWrapper<KingReceiveNoticeLogisticsEntity>().eq("receive_notice_id", kingReceiveNotice.getId()));
            kingReceiveNotice.setLogisticsList(logisticsList);
        });
        return kingReceiveNoticeEntity;
    }

    /**
     * 查询金蝶-收料通知单列表
     * @param kingReceiveNoticeEntity 金蝶-收料通知单
     * @return 金蝶-收料通知单
     */
    @Override
    public List<KingReceiveNoticeEntity> selectKingReceiveNoticeEntityList(KingReceiveNoticeEntity kingReceiveNoticeEntity)
    {
        return kingReceiveNoticeMapper.selectKingReceiveNoticeEntityList(kingReceiveNoticeEntity);
    }

    /**
     * 根据收料通知单id删除其他信息
     * @param id
     */
    private void removeKingReceiveNotice(String id){
        receiveNoticeMaterialService.remove(new LambdaUpdateWrapper<KingReceiveNoticeMaterialEntity>().eq(KingReceiveNoticeMaterialEntity::getReceiveNoticeId,id));
        receiveNoticeMaterialDetailService.remove(new LambdaUpdateWrapper<KingReceiveNoticeMaterialDetailEntity>().eq(KingReceiveNoticeMaterialDetailEntity::getReceiveNoticeId,id));
        receiveNoticeMaterialDetailSerialService.remove(new LambdaUpdateWrapper<KingReceiveNoticeMaterialDetailSerialEntity>().eq(KingReceiveNoticeMaterialDetailSerialEntity::getReceiveNoticeId,id));
        receiveNoticeLogisticsService.remove(new LambdaUpdateWrapper<KingReceiveNoticeLogisticsEntity>().eq(KingReceiveNoticeLogisticsEntity::getReceiveNoticeId,id));
    }

    /**
     * 批量删除金蝶-收料通知单
     * @param ids 需要删除的金蝶-收料通知单ID
     * @return 结果
     */
    @Override
    public int deleteKingReceiveNoticeEntityByIds(String[] ids)
    {
        for(String id : ids){
            removeKingReceiveNotice(id);
        }
        return kingReceiveNoticeMapper.deleteKingReceiveNoticeEntityByIds(ids);
    }

    /**
     * 删除金蝶-收料通知单信息
     * @param id 金蝶-收料通知单ID
     * @return 结果
     */
    @Override
    public int deleteKingReceiveNoticeEntityById(String id)
    {
        removeKingReceiveNotice(id);
        return kingReceiveNoticeMapper.deleteKingReceiveNoticeEntityById(id);
    }


    @Override
    public AjaxResult getKingReceiveNoticeSelect(KingReceiveNoticeSelectQueryDto queryDto){
        queryDto.setPage(queryDto.getPage() - 1);
        List<KingReceiveNoticeSelectVo> list = kingReceiveNoticeMapper.getKingReceiveNoticeSelect(queryDto);
        list.forEach(receiveNoticeVo -> {
            KingReceiveNoticeMaterialQueryDto materialQueryDto = new KingReceiveNoticeMaterialQueryDto();
            materialQueryDto.setReceiveNoticeId(receiveNoticeVo.getId());
            materialQueryDto.setMaterialDetailId(receiveNoticeVo.getMaterialDetailId());
            //累计入库数量(入库单源单为收料通知单1及行号，物料入库数量求和)
            OrderSumResult inventorySumResult = inventoryMaterialService.selectSumReceiptsNumByReceiveNotice(materialQueryDto);
            receiveNoticeVo.setTotalInventoryNum(inventorySumResult.getTotalNum());
            //检验数量
            String checkNum = checkMaterialService.getTotalCheckNumByReceiveNotice(materialQueryDto);
            receiveNoticeVo.setCheckNum(checkNum);
            //合格数量
            String qualifiedNum = checkMaterialService.getTotalQualifiedNumByReceiveNotice(materialQueryDto);
            receiveNoticeVo.setQualifiedNum(qualifiedNum);
            //判退数量
            KingReceiveNoticeMaterialQueryDto rejectQueryDto = new KingReceiveNoticeMaterialQueryDto();
            rejectQueryDto.setReceiveNoticeId(receiveNoticeVo.getId());
            rejectQueryDto.setMaterialDetailId(receiveNoticeVo.getMaterialDetailId());
            rejectQueryDto.setUseDecision(ConstUtil.CHECK_DECISION_REJECT);
            String rejectNum = checkMaterialUseDecisionService.getTotalDecisionNumByByReceiveNotice(rejectQueryDto);
            receiveNoticeVo.setRejectNum(rejectNum);
            //让步接收数量
            KingReceiveNoticeMaterialQueryDto concessionAcceptanceQueryDto = new KingReceiveNoticeMaterialQueryDto();
            concessionAcceptanceQueryDto.setReceiveNoticeId(receiveNoticeVo.getId());
            concessionAcceptanceQueryDto.setMaterialDetailId(receiveNoticeVo.getMaterialDetailId());
            concessionAcceptanceQueryDto.setUseDecision(ConstUtil.CHECK_DECISION_CONCESSION_ACCEPT);
            String concessionAcceptanceNum = checkMaterialUseDecisionService.getTotalDecisionNumByByReceiveNotice(concessionAcceptanceQueryDto);
            receiveNoticeVo.setConcessionAcceptanceNum(concessionAcceptanceNum);
        });
        Integer totalCount = kingReceiveNoticeMapper.queryTotalCount(queryDto);
        PageParam records = new PageParam ();
        records.setRecords ( list ).setTotal ( totalCount );
        return AjaxResult.success ( records );
    }


}
